/**
* @program: src
*
* @description:
*
* @author: Mr.chen
*
* @create: 2020-12-19 11:33
**/
package client

import (
	"github.com/gin-gonic/gin"
	proto "ydd-im/service/account/proto"
	"ydd-im/service/api/define"

	"ydd-im/util/logger"

	"context"

	"github.com/afex/hystrix-go/hystrix"
	"go.uber.org/zap"
)

/**
 * 登录
 * @access  public
 * @param   string     username  账号
 * @param   string     passwd  密码
 * @param   string     client  客户端
 * @param   string     appkey  appkey
 * @return  map[string]interface{} data 用户信息
 * @return  error err
 */
func LoginIsClusterUser(c *gin.Context,username,passwd,client,appkey string) (respon_data *proto.LoginUserResp,err error){
	addr,err := GetBalanceAddrPlus(define.ETCD_SERVER_Account_LIST,true)
	if err != nil {
		return respon_data,err
	}

	//conn,err := grpcConnPlus(addr)
	//if err != nil {
	//	return respon_data,err
	//}
	conn := createGrpcConn(addr,c)
	defer conn.Close()
	hystrix.ConfigureCommand("Login", hystrix.CommandConfig{
		Timeout:               1000,
		MaxConcurrentRequests: 100,
		RequestVolumeThreshold:50,
		ErrorPercentThreshold: 25,
	})
	dataChan := make(chan *proto.LoginUserResp, 1)
	err = hystrix.Do("Login", func() error {
		c :=  proto.NewUserAccountServiceClient(conn)
		resp,err := c.Login(context.Background(), &proto.LoginUserReq{
			Username:username,
			Passwd:passwd,
			Client:client,
			Appkey:appkey,
		})
		if err != nil  {
			return err
		}
		dataChan<-resp
		return nil
	}, nil) // fallback没有处理错误请置为空，否则会处理错误
	if err !=nil {
		logger.GetLg().Error("failed to call",
			zap.Any("err",err),
		)
		return respon_data,err
	}
	if list, ok := <-dataChan;ok {
		close(dataChan)
		return list,nil
	}
	close(dataChan)
	return respon_data,nil
}

/**
 *注册账号
 * @access  public
 * @param   string     username  账号
 * @param   string     passwd  密码
 * @param   string     userkey  用户id
 * @param   string     appkey  appkey
 * @return  mix
 */
func RegisterIsClusterUser(username,passwd,userkey,appkey string) (respon_data *proto.RegisterUserResp,err error){
	addr,err := GetBalanceAddrPlus(define.ETCD_SERVER_Account_LIST,true)
	if err != nil {
		return respon_data,err
	}
	conn,err := grpcConnPlus(addr)
	defer conn.Close()
	if err != nil {
		return respon_data,err
	}
	hystrix.ConfigureCommand("Register", hystrix.CommandConfig{
		Timeout:               1000,
		MaxConcurrentRequests: 100,
		RequestVolumeThreshold:50,
		ErrorPercentThreshold: 25,
	})
	dataChan := make(chan *proto.RegisterUserResp, 1)
	err = hystrix.Do("Register", func() error {
		c :=  proto.NewUserAccountServiceClient(conn)
		resp,err := c.Register(context.Background(), &proto.RegisterUserReq{
			Username:username,
			Passwd:passwd,
			Userkey:userkey,
			Appkey:appkey,
		})
		if err != nil  {
			return err
		}
		dataChan<-resp
		return nil
	}, nil) // fallback没有处理错误请置为空，否则会处理错误
	if err !=nil {
		logger.GetLg().Error("failed to call",
			zap.Any("err",err),
		)
		return respon_data,err
	}
	if list, ok := <-dataChan;ok {
		close(dataChan)
		return list,nil
	}
	close(dataChan)
	return respon_data,nil
}


/**
 * 获取用户token有效性
 * @access  public
 * @param   string     token  用户token
 * @return  mix
 */
func GetUserInfoByTokenIsCluster(token string) (respon_data *proto.UserInfoByTokenResp,err error){
	addr,err := GetBalanceAddrPlus(define.ETCD_SERVER_Account_LIST,true)
	if err != nil {
		return respon_data,err
	}
	conn,err := grpcConnPlus(addr)
	defer conn.Close()
	if err != nil {
		return respon_data,err
	}
	hystrix.ConfigureCommand("UserInfoByToken", hystrix.CommandConfig{
		Timeout:               1000,
		MaxConcurrentRequests: 100,
		RequestVolumeThreshold:50,
		ErrorPercentThreshold: 25,
	})
	dataChan := make(chan *proto.UserInfoByTokenResp, 1)
	err = hystrix.Do("UserInfoByToken", func() error {
		c :=  proto.NewUserAccountServiceClient(conn)
		resp,err := c.GetUserInfoByToken(context.Background(), &proto.UserInfoByTokenReq{
			Token:token,
		})
		if err != nil  {
			return err
		}
		dataChan<-resp
		return nil
	}, nil) // fallback没有处理错误请置为空，否则会处理错误
	if err !=nil {
		logger.GetLg().Error("failed to call",
			zap.Any("err",err),
		)
		return respon_data,err
	}
	if list, ok := <-dataChan;ok {
		close(dataChan)
		return list,nil
	}
	close(dataChan)
	return respon_data,nil
}